<script setup lang="ts">
import { ref, defineEmits, onMounted, computed } from 'vue'
import { useProjectStore, ExecutionMethod, ExpectedResult, NextStepCondition, Step } from '../stores/store'
import ConditionItem from './ConditionItem.vue'
import Sortable from 'sortablejs'

declare global {
  interface Window {
    pywebview: {
      api: any
    },
    debug: (text: string, type: any) => void // 输出信息至控制台
    printToTerm: (msg: string, level?: 'info' | 'error' | 'warn' | 'command' | 'debug' | 'success') => void // 输出信息至终端
    setTaskBar: (text: string, progress?: number) => void // 输出信息至任务栏
  }
}
const props = defineProps({
  step: {
    type: Object,
    required: true
  },
  index: {
    type: Number,
    required: true
  },
  taskName: {
    type: String,
    required: true
  },
  additionalConditionTypes: {
    type: Array<{ label: string, value: string }>,
    default: () => []
  }
})

const emit = defineEmits(['delete', 'add'])
// 添加折叠状态，默认展开
const isCollapsed = ref(false)
// 使用store
const projectStore = useProjectStore()

// 获取当前任务名称
const getCurrentTaskName = () => {
  // 优先使用从父组件传递的taskName
  if (props.taskName) {
    return props.taskName
  }

  // 从store获取第一个任务名称
  return projectStore.settings.tasks[0]?.name || ''
}

// 操作类型选项
const actionTypes = [
  { label: '鼠标左键点击', value: 'left_click' },
  { label: '鼠标右键点击', value: 'right_click' },
  { label: '鼠标中键点击', value: 'middle_click' },
  { label: '鼠标双击', value: 'double_click' },
  { label: '鼠标左键按下', value: 'left_down' },
  { label: '鼠标左键弹起', value: 'left_up' },
  { label: '鼠标右键按下', value: 'right_down' },
  { label: '鼠标右键弹起', value: 'right_up' },
  { label: '鼠标中键按下', value: 'middle_down' },
  { label: '鼠标中键弹起', value: 'middle_up' },
  { label: '鼠标滚轮向上', value: 'wheel_up' },
  { label: '鼠标滚轮向下', value: 'wheel_down' },
  { label: '鼠标移动', value: 'move_to' },
  { label: '按下键盘按键', value: 'key_press' },
  { label: '按下键盘组合键', value: 'key_press_combination' },
  { label: '输入文本SendString', value: 'input_text' },
  { label: '输入文本SendStringIme', value: 'input_text_ime' },
  { label: '输入文本SendStringIme2', value: 'input_text_ime2' },
  { label: '输入字符串KeyPressStr', value: 'input_string' }, // 只支持标准ASCII可见字符
  { label: '设置剪切板内容', value: 'setClipboard' },
  { label: '粘贴SendPaste', value: 'send_paste' },
  { label: '等待', value: 'wait' }
]

// 按操作类型分类
const actionTypeCategories = {
  target: [
    'left_click', 'right_click', 'middle_click', 'double_click',
    'left_down', 'left_up', 'right_down', 'right_up',
    'middle_down', 'middle_up', 'wheel_up', 'wheel_down', 'move_to', 'send_paste'
  ],
  key: ['key_press', 'key_press_combination'],
  text: [
    'input_text', 'input_text_ime', 'input_text_ime2',
    'input_string', 'setClipboard'
  ],
  wait: ['wait']
}

// 判断操作类型属于哪个分类
const getActionCategory = (action) => {
  for (const [category, actions] of Object.entries(actionTypeCategories)) {
    if (actions.includes(action)) {
      return category
    }
  }
  return null
}

// 失败处理选项
const failureHandlingOptions = [
  { label: '重复步骤', value: 'repeat_step' },
  { label: '等待指定秒数后再次判断预期结果是否满足', value: 'wait_and_retry' },
  { label: '跳转到指定步骤', value: 'jump_to_step' },
  { label: '抛出错误', value: 'raise_error' }
]

// 更新步骤名称
const updateStepName = (name: string) => {
  const updatedStep = { ...props.step, name } as Step
  // 获取当前任务名称（需要从父组件或store中获取）
  const taskName = getCurrentTaskName()
  projectStore.updateStep(taskName, props.index, updatedStep)
}

// 更新执行方法列表
const updateExecutionMethods = (methods: ExecutionMethod[]) => {
  const updatedStep = { ...props.step, executionMethods: methods } as Step
  const taskName = getCurrentTaskName()
  projectStore.updateStep(taskName, props.index, updatedStep)
}

// 添加新的执行方法
const addExecutionMethod = () => {
  if (!props.step.executionMethods) {
    props.step.executionMethods = []
  }
  const updatedMethods = [...props.step.executionMethods, {
    id: projectStore.generateUniqueId(), // 添加唯一ID
    action: 'left_click',
    target: ''
  }]
  updateExecutionMethods(updatedMethods)
}


// 删除执行方法
const removeExecutionMethod = (index: number) => {
  if (props.step.executionMethods.length > 1) {
    const updatedMethods = [...props.step.executionMethods]
    updatedMethods.splice(index, 1)
    updateExecutionMethods(updatedMethods)
  } else {
    alert('至少需要保留一个执行方法')
  }
}

// 更新单个执行方法
const updateSingleExecutionMethod = (index: number, method: ExecutionMethod) => {
  const updatedMethods = [...props.step.executionMethods]
  updatedMethods[index] = method
  updateExecutionMethods(updatedMethods)
}

// 更新失败处理方式
const updateFailureHandlingAction = (action: string) => {
  const updatedStep = {
    ...props.step,
    failureHandling: {
      ...props.step.failureHandling,
      action
    }
  } as Step
  const taskName = getCurrentTaskName()
  projectStore.updateStep(taskName, props.index, updatedStep)
}

// 更新失败处理值
const updateFailureHandlingValue = (value: string) => {
  const updatedStep = {
    ...props.step,
    failureHandling: {
      ...props.step.failureHandling,
      value
    }
  } as Step
  const taskName = getCurrentTaskName()
  projectStore.updateStep(taskName, props.index, updatedStep)
}

// 添加/删除执行条件
const addExecutionCondition = () => {
  const taskName = getCurrentTaskName()
  projectStore.updateExecutionCondition(taskName, props.index, {
    conditionType: 'none',
    value: ''
  })
}

const removeExecutionCondition = () => {
  const taskName = getCurrentTaskName()
  projectStore.updateExecutionCondition(taskName, props.index, null)
}

// 添加/删除条件跳转
const addNextStepCondition = () => {
  const taskName = getCurrentTaskName()
  projectStore.addNextStepCondition(taskName, props.index)
}

const removeNextStepCondition = (index: number) => {
  const taskName = getCurrentTaskName()
  projectStore.deleteNextStepCondition(taskName, props.index, index)
}

// 截图功能
const captureImage = async (conditionIndex: number) => {
  try {
    const res = await window.pywebview.api.capture_screen() // res = {"suc": True, "image": image}
    if (res && res.suc) {
      const taskName = getCurrentTaskName()

      // 根据条件索引更新对应的条件值
      if (conditionIndex === -2) {
        // 执行条件的截图
        if (props.step.executionCondition) {
          const updatedCondition = { ...props.step.executionCondition, value: res.image }
          projectStore.updateExecutionCondition(taskName, props.index, updatedCondition)
        }
      } else if (conditionIndex === -1) {
        // 预期结果的截图
        const updatedCondition = { ...props.step.expectedResult, value: res.image }
        projectStore.updateExpectedResult(taskName, props.index, updatedCondition)
      } else if (conditionIndex >= 0 && props.step.nextStepConditions && conditionIndex < props.step.nextStepConditions.length) {
        // 条件跳转的截图
        const updatedCondition = { ...props.step.nextStepConditions[conditionIndex], value: res.image }
        projectStore.updateNextStepCondition(taskName, props.index, conditionIndex, updatedCondition)
      }
      console.log('截图成功:', res)
    } else {
      console.error('截图失败:', res)
    }
  } catch (error) {
    console.error('截图过程中出现错误:', error)
  }
}

/**
 * 测试步骤
 */
const test = async () => {
  const updatedStep = props.step
  await window.pywebview.api.testStep(updatedStep)
}

// 更新执行条件
const updateExecutionCondition = (newCondition: ExpectedResult) => {
  const taskName = getCurrentTaskName()
  // 确保执行条件是一个对象而不是数组
  if (newCondition && typeof newCondition === 'object' && !Array.isArray(newCondition)) {
    projectStore.updateExecutionCondition(taskName, props.index, newCondition)
  } else {
    // 如果不是对象，使用默认值或空数组
    projectStore.updateExecutionCondition(taskName, props.index, null)
  }
}

// 更新预期结果
const updateExpectedResult = (newCondition: ExpectedResult) => {
  const taskName = getCurrentTaskName()
  projectStore.updateExpectedResult(taskName, props.index, newCondition)
}

// 更新条件跳转
const updateNextStepCondition = (conditionIndex: number, newCondition: NextStepCondition) => {
  const taskName = getCurrentTaskName()
  projectStore.updateNextStepCondition(taskName, props.index, conditionIndex, newCondition)
}

const executionMethodsContainer = ref(null)
onMounted(() => {
  if (executionMethodsContainer.value) {
    Sortable.create(executionMethodsContainer.value, {
      animation: 150,
      handle: '.cursor-move',
      onEnd: function(evt: any) {
        const oldIndex = evt.oldIndex
        const newIndex = evt.newIndex
        if (oldIndex !== newIndex && oldIndex !== undefined && newIndex !== undefined) {
          // 重新排序executionMethods数组
          const methods = [...props.step.executionMethods]
          const movedItem = methods.splice(oldIndex, 1)[0] // 在老索引处删除一个元素，返回删除的元素
          methods.splice(newIndex, 0, movedItem) // 将删除的元素添加到新索引处

          // 更新store中的数据
          updateExecutionMethods(methods)
        }
      }
    })
  }
})

// 切换折叠状态
const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value
}

// 提供给父组件的拖动句柄类名
const dragHandleClass = computed(() => {
  return isCollapsed.value ? 'step-cursor-move' : ''
})
</script>

<template>
  <div :class="['task-step p-4 mb-4 border border-gray-300 rounded', dragHandleClass]">
    <div class="step-header flex justify-between items-center mb-3">
      <h3 class="text-lg font-semibold">步骤 {{ index + 1 }}: {{ step.name }}</h3>
      <div>
        <button @click="toggleCollapse" class="px-2 py-1 bg-gray-500 text-white rounded m-1">
          {{ isCollapsed ? '展开' : '折叠' }}
        </button>
        <button @click="$emit('add', props.index)" class="px-2 py-1 bg-green-500 text-white rounded m-1">添加</button>
        <button @click="$emit('delete')" class="px-2 py-1 bg-red-500 text-white rounded m-1">删除</button>
        <button @click="test" class="px-2 py-1 bg-amber-500 text-white rounded m-1">测试</button>
      </div>
    </div>

    <div v-if="!isCollapsed">
      <div class="step-name mb-3">
        <label class="block font-medium mb-1">步骤名称:</label>
        <input
          :value="step.name"
          @input="updateStepName(($event.target as HTMLInputElement).value)"
          type="text"
          class="w-full p-2 border border-gray-300 rounded"
          placeholder="输入步骤名称"
        />
      </div>

      <!-- 执行条件 -->
      <div class="execution-conditions mb-4 bg-amber-50">
        <div class="flex justify-between items-center mb-2 ">
          <h4 class="font-medium">执行条件:</h4>
          <div>
            <button
              v-if="!step.executionCondition"
              @click="addExecutionCondition"
              class="px-2 py-1 bg-blue-500 text-white rounded text-sm"
            >
              添加条件
            </button>
            <button
              v-else
              @click="removeExecutionCondition"
              class="px-2 py-1 bg-red-500 text-white rounded text-sm"
            >
              删除条件
            </button>
          </div>
        </div>

        <div v-if="step.executionCondition">
          <ConditionItem
            :condition="step.executionCondition"
            :index="-2"
            :additional-condition-types="props.additionalConditionTypes"
            @update:condition="updateExecutionCondition"
            @capture="captureImage"
          />
        </div>
        <div v-else class="text-gray-500 italic text-sm">
          无执行条件
        </div>
      </div>

      <!-- 执行操作 -->
      <div class="execution-method mb-4 bg-blue-50">
        <div class="flex justify-between items-center mb-2">
          <h4 class="font-medium">执行方法:</h4>
          <button @click="addExecutionMethod" class="px-2 py-1 bg-blue-500 text-white rounded text-sm">添加操作</button>
        </div>

        <div
          ref="executionMethodsContainer"
          class="execution-methods-container"
        >
          <div
            v-for="(method, methodIndex) in step.executionMethods"
            :key="method.id"
            class="border border-gray-200 rounded p-3 mb-3 hover:border-red-400 cursor-move execution-method-item"
          >
            <div class="flex justify-between items-center mb-2 cursor-move">
              <span class="font-medium">操作 {{ methodIndex + 1 }}</span>
              <button
                v-if="step.executionMethods.length > 1"
                @click="removeExecutionMethod(methodIndex)"
                class="px-2 py-1 bg-red-500 text-white rounded text-sm"
              >
                删除
              </button>
            </div>

            <div class="flex items-center mb-2">
              <select
                :value="method.action"
                @change="updateSingleExecutionMethod(methodIndex, {...method, action: ($event.target as HTMLSelectElement).value})"
                class="p-2 border border-gray-300 rounded mr-2 w-60"
              >
                <option
                  v-for="action in actionTypes"
                  :key="action.value"
                  :value="action.value"
                >
                  {{ action.label }}
                </option>
              </select>

              <div
                v-if="getActionCategory(method.action) === 'target'"
                class="flex items-center flex-1">
                <label class="font-medium mb-1 pl-5 pr-2">{{
                    method.action === 'send_paste' ? '粘贴位置:' : '目标位置:'
                  }}</label>
                <div class="flex items-center flex-1">
                  <input
                    :value="method.target"
                    @input="updateSingleExecutionMethod(methodIndex, {...method, target: ($event.target as HTMLInputElement).value})"
                    type="text"
                    class="flex-grow p-2 border border-gray-300 rounded mr-2"
                    :placeholder="method.action === 'send_paste' ? '输入坐标或图像路径' : '输入坐标或图像路径'"
                  />
                  <button
                    @click="captureImage(-2)"
                    class="ml-2 px-2 py-1 bg-blue-500 text-white rounded text-xs"
                  >
                    截图
                  </button>
                </div>
              </div>
              <div v-else-if="getActionCategory(method.action) === 'key'" class="flex items-center flex-1">
                <label class="font-medium mb-1 pl-5 pr-2">按键:</label>
                <input
                  :value="method.key"
                  @input="updateSingleExecutionMethod(methodIndex, {...method, key: ($event.target as HTMLInputElement).value})"
                  type="text"
                  class="w-full p-2 border border-gray-300 rounded items-center flex-1"
                  placeholder="输入按键"
                />
              </div>
              <div v-else-if="getActionCategory(method.action) === 'text'" class="flex items-center flex-1">
                <label class="font-medium mb-1 pl-5 pr-2">{{
                    method.action === 'setClipboard' ? '剪切板内容:' :
                      method.action === 'input_string' ? '输入字符串:' : '输入文本:'
                  }}</label>
                <input
                  :value="method.text"
                  @input="updateSingleExecutionMethod(methodIndex, {...method, text: ($event.target as HTMLInputElement).value})"
                  type="text"
                  class="w-full p-2 border border-gray-300 rounded items-center flex-1"
                  :placeholder="method.action === 'input_string' ? '输入字符串(仅支持标准ASCII可见字符)' :
              method.action === 'setClipboard' ? '输入要设置到剪切板的内容' :
              method.action === 'input_text_ime'? '输入文本，需配合dx.public.input.ime属性': '输入文本'"
                />
              </div>
              <div v-else-if="getActionCategory(method.action) === 'wait'" class="flex items-center flex-1">
                <label class="font-medium mb-1 pl-5 pr-2">等待时间(秒):</label>
                <input
                  :value="method.target"
                  @input="updateSingleExecutionMethod(methodIndex, {...method, target: ($event.target as HTMLInputElement).value})"
                  type="text"
                  class="w-full p-2 border border-gray-300 rounded items-center flex-1"
                  placeholder="输入等待时间"
                />
              </div>
            </div>

          </div>
        </div>
      </div>

      <!-- 预期结果 -->
      <div class="expected-results mb-4 bg-yellow-100">
        <h4 class="font-medium mb-2">预期结果:</h4>

        <ConditionItem
          :condition="step.expectedResult"
          :index="-1"
          :additional-condition-types="props.additionalConditionTypes"
          @update:condition="updateExpectedResult"
          @capture="captureImage"
        />
      </div>

      <!-- 失败处理 -->
      <div class="failure-handling mb-4">
        <h4 class="font-medium mb-2">失败处理方式:</h4>

        <div class="flex items-center">
          <select
            :value="step.failureHandling?.action || 'wait_and_retry'"
            @change="updateFailureHandlingAction(($event.target as HTMLSelectElement).value)"
            class="border border-gray-300 rounded w-96 flex-0 p-2"
          >
            <option
              v-for="option in failureHandlingOptions"
              :key="option.value"
              :value="option.value"
            >
              {{ option.label }}
            </option>
          </select>

          <!-- 当选择需要值的失败处理方式时，显示输入框 -->
          <div v-if="step.failureHandling?.action === 'wait_and_retry'" class="flex flex-1 items-center">
            <label class="font-medium w-40 pr-2 text-right">等待时间(秒):</label>
            <input
              :value="step.failureHandling?.value"
              @input="updateFailureHandlingValue(($event.target as HTMLInputElement).value)"
              type="text"
              class="border border-gray-300 rounded flex-1 p-2"
              placeholder="输入等待时间"
            />
          </div>

          <div v-else-if="step.failureHandling?.action === 'jump_to_step'" class="flex flex-1 items-center">
            <label class="font-medium w-40 pr-2 text-right">目标步骤名称:</label>
            <input
              :value="step.failureHandling?.value"
              @input="updateFailureHandlingValue(($event.target as HTMLInputElement).value)"
              type="text"
              class="border border-gray-300 rounded flex-1 p-2"
              placeholder="输入目标步骤名称"
            />
          </div>
        </div>

      </div>

      <!-- 条件跳转 -->
      <div class="next-step-conditions">
        <div class="flex justify-between items-center mb-2">
          <h4 class="font-medium">条件跳转:</h4>
          <button @click="addNextStepCondition" class="px-2 py-1 bg-blue-500 text-white rounded text-sm">
            添加条件跳转
          </button>
        </div>

        <ConditionItem
          v-for="(condition, i) in step.nextStepConditions"
          :key="i"
          :condition="condition"
          :index="i"
          :show-next-step="true"
          :additional-condition-types="props.additionalConditionTypes"
          @remove="removeNextStepCondition"
          @update:condition="(newCond) => updateNextStepCondition(i, newCond)"
          @capture="captureImage"
        />
      </div>
    </div>
  </div>
</template>

<style scoped>
.condition-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.cursor-move {
  cursor: move;
}

.step-cursor-move {
  cursor: move;
}

.execution-methods-container {
  min-height: 50px;
}
</style>
